<?php

namespace Yunque\Client\service;

use Yunque\Client\Config;
use Yunque\Client\driver\Driver;
use Yunque\Client\utils\Bytes;
use Yunque\Client\proto\ReplyBodyProto;
use Yunque\Client\proto\ReplyBodysPubProto;
use Yunque\Client\proto\SendActProto;
use Yunque\Client\proto\SendTypeProto;

class ReplyBodyService
{
    public Driver $pubService;
    public string $channel = "message";
    public string  $driver;
    public function initConfig(): array
    {
     return   Config::init();
    }
    public static function init(array $config = null, $driver=null)
    {
        $self = new ReplyBodyService( $config,$driver);
        return $self;
    }

    public function __construct(array $config = null, $driver=null)
    {

        if ($driver==null){
            $driver=$this->initConfig()['default'];
        }
        if ($config == null) {
            $config =$this->initConfig()["driver"][$driver];
        }

        if ($driver == "redis") {
            $this->pubService = \Yunque\Client\driver\Redis::init($config);

        } elseif ($driver == "kafka") {
            $this->pubService = \Yunque\Client\driver\Kafka::init($config);
        } else {
            return null;
        }
        return $this;
    }


    /*
     * 推送消息给指定用户
     */
    public function sendTo(string $uid, ReplyBodyProto $msg): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
        $ReplyBodysPubProto->setUid($uid);
        $ReplyBodysPubProto->setMsg([$msg]);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDUID, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送消息给指定用户 批量
     */
    public function sendTos(string $uid, array $msgs): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
        $ReplyBodysPubProto->setUid($uid);
        $ReplyBodysPubProto->setMsg($msgs);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDUID, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送消息给指定多个用户
     * 多个uid 逗号分割
     * params $uids=uid1,uid2,uid3
     */
    public function sendToUids(string $uids, array $msgs): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
        $ReplyBodysPubProto->setUid($uids);
        $ReplyBodysPubProto->setMsg($msgs);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDUIDS, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送消息给指定用户的某个设备
     */
    public function sendToDid(string $uid, string $did, ReplyBodyProto $msg): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
        $ReplyBodysPubProto->setDid($did);
        $ReplyBodysPubProto->setSid("beijing1");
        $ReplyBodysPubProto->setUid($uid);
        $ReplyBodysPubProto->setMsg([$msg]);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDUIDDID, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送批量消息给指定用户的某个设备
     */
    public function sendToDids(string $uid, string $did, array $msgs): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
        $ReplyBodysPubProto->setDid($did);
        $ReplyBodysPubProto->setSid("beijing1");
        $ReplyBodysPubProto->setUid($uid);
        $ReplyBodysPubProto->setMsg($msgs);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDUIDDID, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送消息给所有人
     * @params $msg =ReplyBodyProto
     */
    public function sendToAll(ReplyBodyProto $msg): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
//        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
//        $ReplyBodysPubProto->setUid("");
        $ReplyBodysPubProto->setMsg([$msg]);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDALL, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 推送消息给所有人
     * @params $msg =ReplyBodyProto
     */
    public function sendToAlls(array $msgs): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
//        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
//        $ReplyBodysPubProto->setUid("");
        $ReplyBodysPubProto->setMsg($msgs);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDALL, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }

    /*
     * 遍历消息推给接收人
     * @params $msg =[ReplyBodyProto]
     */
    public function sendList(array $msg): bool
    {
        $ReplyBodysPubProto = new ReplyBodysPubProto();
//        $ReplyBodysPubProto->setDid("");
        $ReplyBodysPubProto->setSid("beijing1");
//        $ReplyBodysPubProto->setUid("");
        $ReplyBodysPubProto->setMsg([$msg]);
        $packed = $ReplyBodysPubProto->serializeToString();
        $buff = [SendActProto::SENDLIST, SendTypeProto::REPLY];
        $buffto = Bytes::tostr($buff);
        $buffto = $buffto . $packed;
        try {

            $ret = $this->pubService->sendTo($this->channel, $buffto);
            if ($ret == 1) {
                print_r("ok");
                return true;
            }
            return false;
        } catch (\RedisException $e) {
            print_r($e);
        }
        return false;

    }
}